package bby.app.fettool;

import bby.app.keytools.AES;
import bby.app.keytools.RSA;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.*;
import java.security.KeyPair;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ReceiverPage extends JPanel
{
    final String LOG_FILE_NAME=Config.LOG_FILE;
    JTextField portInput,pvtKeyInput,hostView,pubKeyInput,keyBitsInput;
    JTextArea fileInfoView,outMsg;
    JButton openBt,decodeBt,mkKeyBt;
    JPanel title,msgBody,keyBody,recvBody;
    JList<String> listView;
    Vector<RecvFile> fileList;
    RecvFile selFile;
    StringBuffer showMsg;
    MyManager myManager;
    boolean isOpened = false;
    Server server;
    private void initVariable(){
        hostView=new JTextField("127.0.0.1");
        pvtKeyInput = new JTextField(20);
        pubKeyInput = new JTextField(20);
        showMsg=new StringBuffer();
        portInput = new JTextField(5);
        keyBitsInput = new JTextField(3);
        fileInfoView = new JTextArea();
        outMsg = new JTextArea();
        openBt = new JButton("开始");
        decodeBt = new JButton("解密");
        mkKeyBt=new JButton("重置");
        title = new JPanel();
        msgBody = new JPanel();
        keyBody = new JPanel();
        recvBody = new JPanel();
    }
    public void setMyManager(MyManager myManager){
        this.myManager=myManager;
    }
//    public void setPrivateKey(String key){
//        pvtKeyInput.setText(key);
//    }
//    public void setPublicKey(String key){
////        p.setText(key);
//    }
    private void initWindow(){
        setLayout(new GridLayout(3,1));
        //outMsg.setPreferredSize(new Dimension (420,150));;
//        outMsg.setEditable(false);

        JTextField textMsg = new JTextField("此界面是接收文件界面！");
        textMsg.setForeground(Color.RED);
        textMsg.setHorizontalAlignment(JTextField.CENTER);
        textMsg.setFont(new Font ("宋体",Font.BOLD,20));
        textMsg.setEditable(false);
        
        JTextField ip=new JTextField("您的ip:");
        ip.setEditable(false);
        ip.setBorder(null);
        hostView.setPreferredSize(new Dimension (80,20));
        hostView.setEditable(false);
        hostView.setHorizontalAlignment(JTextField.CENTER);

        JTextField p = new JTextField("端口：");
        p.setBackground(null);
        p.setBorder(null);
        portInput.setText("8080");
        portInput.setHorizontalAlignment(JTextField.CENTER);

        JTextField pub = new JTextField("公钥：");
        pub.setEditable(false);
        pub.setBorder(null);
        keyBody.add(pub);
        keyBody.add(pubKeyInput);

        keyBitsInput.setText("1024");

        JTextField pvt = new JTextField("私钥：");
        pvt.setEditable(false);
        pvt.setBorder(null);
        keyBody.add(pvt);
        keyBody.add(pvtKeyInput);

        JTextField bit = new JTextField("位数：");
        bit.setEditable(false);
        bit.setBorder(null);

        keyBody.add(bit);
        keyBody.add(keyBitsInput);
        keyBody.add(mkKeyBt);
        openBt.setFocusPainted(false);
        JPanel titleBody=new JPanel();
        titleBody.add(ip);
        titleBody.add(hostView);
        titleBody.add(p);
        titleBody.add(portInput);
        titleBody.add(openBt);
        title.setLayout(new GridLayout(3,1));
        title.add(textMsg);
        title.add(titleBody);
        title.add(keyBody);
        add(title);

        JScrollPane outMsgScroll=new JScrollPane(outMsg);
        outMsgScroll.setPreferredSize(new Dimension (420,150));
        add(outMsgScroll);
//        outMsgScroll.setBounds(13, 10, 420, 150);

//        setLayout(new FlowLayout());

        JScrollPane li=new JScrollPane(listView);
        li.setPreferredSize(new Dimension(300, 150));
        recvBody.add(li);
        recvBody.add(fileInfoView);
        recvBody.add(decodeBt);
        add(recvBody);
        print("初始化完成，可以开始监听了！");
    }
    private void initFileview() {
        listView=new JList<>();
        listView.setFont(new Font ("宋体",Font.BOLD,10));
        listView.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);//单选
        fileInfoView.setPreferredSize(new Dimension (300,150));
        fileInfoView.setEditable(false);
        decodeBt.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                String pvtKey=pvtKeyInput.getText();
                if (selFile == null) {
                    print("没有选择文件！！");
                    return;
                }
                File outfile = new File(Config.RECV_DIR+selFile.name.replace(".bbyend",""));
                if(selFile.isDecode){//已经解密了
                    try {
                        Runtime.getRuntime().exec("explorer.exe /select," + outfile.getPath());
                    } catch (IOException ioException) {
                        ioException.printStackTrace();
                    }
                    return;
                }
                if (pvtKey.length() == 0) {
                    print("请输入私钥！！");
                    return;
                }
                try {
                    File file = new File(Config.RECV_DIR+selFile.name);
                    if (!file.isFile()) {
                        print("文件丢失！");
                        return;
                    }
                    if (!outfile.isFile()) outfile.createNewFile();
                    print("正在解密文件 " + file.getName()+ ",文件大小：" + (file.length()) + " Byte");
                    print("用私钥解密对称秘钥...");
                    print("私钥："+pvtKey);
                    print("对称秘钥（密文）："+pvtKey);
                    String key = RSA.decrypt(selFile.enkey,RSA.getPrivateKey(pvtKey));
                    print("解密后的对称秘钥："+key);
                    print("解密文件中...");
                    BufferedReader br = new BufferedReader(new FileReader(file));
                    OutputStream os = new FileOutputStream(outfile);
                    String line;
                    while ((line = br.readLine()) != null) {
                        byte bts[] = AES.aesDecrypt(line,key);
                        if (bts == null) {
                            print("文件格式错误，解密失败！");
                            return;
                        }
                        os.write(bts);
                        os.flush();
                    }
                    br.close();
                    os.close();
                    print("解密完成！");
                    print("明文文件：" + outfile.getPath());
                    myManager.flashFileList();
                    Runtime.getRuntime().exec("explorer.exe /select," + outfile.getPath());
                } catch (Exception exception) {

                }
            }
        });
        listView.addListSelectionListener(new ListSelectionListener(){
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if (e.getValueIsAdjusting()||listView.getSelectedIndex()<1)return;
                selFile = fileList.get(listView.getSelectedIndex()-1);
                fileInfoView.setText(selFile.toString());
                if (selFile.isDecode) decodeBt.setText("打开");
                else decodeBt.setText("解密");
            }
        });
    }
    public void flashFileList(Vector<RecvFile> list){
        if (list==null){
            print("list为null");
            return;
        }
        this.fileList=list;
        Vector<String> listStr= new Vector<>();
        listStr.add("文件名\u3000接收时间");
        for (RecvFile f:list)
            listStr.add(f.name+"\u3000"+f.time);
        listView.setListData(listStr);
    }
    public void print(String str){
        System.out.println("输出："+str);
        showMsg.append(">> "+str+"\n");
        outMsg.setText(showMsg.toString());
        outMsg.setSelectionStart(showMsg.toString().length());
    }
    public void addLog(StringBuffer sb){
        showMsg.append(sb);
        outMsg.setText(showMsg.toString());
    }
    public boolean saveLog(){
        try {
            BufferedWriter outputStream = new BufferedWriter(new FileWriter(LOG_FILE_NAME));
            outputStream.write(showMsg.toString());
            outputStream.flush();
            outputStream.close();
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
//    public show()
    ReceiverPage(){
        initVariable();
        initFileview();
        initWindow();

        mkKeyBt.addMouseListener(new MouseAdapter(){
            @Override
            public void mouseClicked(MouseEvent e) {
                try {
                    int bits=Integer.parseInt(keyBitsInput.getText());
                    print("正在重新生成秘钥对，秘钥位数为："+bits+"位！");
                    myManager.makeKeyPair(bits);
                }catch (Exception ex) {
                    ex.printStackTrace();
                    print("创建秘钥出错,请检查位数配置是否合法！");
                }

            }
        });
        openBt.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (isOpened) closeServe();
                else openServe();
                super.mouseClicked(e);
            }
        });
    }


    private void openServe(){
        int port=8888;
        try {
            port = Integer.parseInt(portInput.getText());
        }catch (Exception e){
            print("端口号需要是数字！！");
            return;
        }
        if (pubKeyInput.getText().length()==0&&!myManager.loadKeypair()){
            print("没有保存的公钥，将为您随机生成！");
            try {
                int bits=Integer.parseInt(keyBitsInput.getText());
                print("正在重新生成秘钥对，秘钥位数为："+bits+"位！");
                myManager.makeKeyPair(bits);
            }catch (Exception ex) {
                ex.printStackTrace();
                print("创建秘钥出错,请检查位数配置是否合法！");
            }
        }else {
            print("已有公钥，直接开启！");
            print("当前公钥为"+pubKeyInput.getText());
            server=new Server(myManager);
            if(server.init(port)){//看是否准备完成
                server.start();
                hostView.setText(Config.getHost());
                isOpened=true;
                openBt.setBackground(Color.red);
                openBt.setText("停止");
                print("已打开监听，您的ip是："+hostView.getText());
            } else {
                print("打开服务器失败，请检查端口设置！");
                return;
            }
        }

    }
    private void closeServe(){
        server.close();
        isOpened=false;
        openBt.setBackground(null);
        openBt.setText("开始");
        print("已关闭！");
    }

    public void setKeyPair(String pub,String pvt) {
        pubKeyInput.setText(pub);
        pvtKeyInput.setText(pvt);
    }
}